package cn.iune.erp.inventory;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.justep.baas.Utils;
import com.justep.baas.data.Row;
import com.justep.baas.data.RowState;
import com.justep.baas.data.Table;
import com.justep.baas.data.Transform;

@Transactional
@Service
public class StorageItemServiceImpl implements IStorageItemService {
	
	private final Logger log = LogManager.getLogger(this);

	@Autowired
	private IStorageItemDao dao;
	
	
	@Transactional
	@Override
	public void insert(StorageItem obj) {
		// TODO Auto-generated method stub
		dao.insert(obj);
	}
	
	@Transactional
	@Override
	public void delete(String fID) {
		// TODO Auto-generated method stub
		dao.delete(fID);
	}
	
	@Transactional
	@Override
	public void update(StorageItem obj) {
		// TODO Auto-generated method stub
		dao.update(obj);
	}
	
	@Override
	public List<StorageItem> getAll() {
		// TODO Auto-generated method stub
		return dao.getAll();
	}
	
	@Override
	public StorageItem getByID(String fID) {
		// TODO Auto-generated method stub
		return dao.getByID(fID);
	}
	
	
	@Transactional
	@Override
	public JSONObject save(JSONObject object) throws ParseException  {
		// TODO Auto-generated method stub
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		
		JSONObject data = new JSONObject();
		data.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		List<String> idsNew = new ArrayList<String>();
		List<String> idsDel = new ArrayList<String>();

		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			StorageItem obj = JSON.toJavaObject(javaObject, StorageItem.class);
			if(RowState.NEW.equals(obj.getRowState())){
				dao.insert(obj);
				idsNew.add(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				dao.update(obj);
				idsDel.add(obj.getfID());
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				StorageItem objNew = dao.update(obj);
				//返回+1后的version到前台BizData中进行刷新，使得前台的version与后台的一致。
				///////////////////////////////////////////////////////////////////////
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
				//////////////////////////////////////////////////////////////////////
			}
		}
		
		data.put("rows", rows);
		data.put("idsNew", idsNew);
		data.put("idsDel", idsDel);
		
		return data;
	}


	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IStorageItemService#getByNo(java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public StorageItem getByNo(String storageID, String itemID){
		return dao.getByNo(storageID, itemID);
	}

	@Override
	public List<StorageItem> getByStorageID(String storageID) {
		return dao.getByStorageID(storageID);
	}

	@Override
	public List<StorageItem> getByItemID(String itemID, String enterpriseNo) {
		return dao.getByItemID(itemID, enterpriseNo);
	}
		
	
	//门店商品列表
	@Override
	public List<StorageItem> getList(String enterpriseNo) {
		return dao.getList(enterpriseNo);
	}

	@Override
	public List<StorageItem> getList(String storehouseID, String enterpriseNo) {
		return dao.getList(storehouseID, enterpriseNo);
	}
	
	//指定商品的库位列表
	@Override
	public List<StorageItem> getStorageList(String storehouseID, String itemID) {
		return dao.getStorageList(storehouseID, itemID);
	}

	//插入一行记录
	@Transactional
	@Override
	public StorageItem insert(
			String storageID
			, String storehouseID
			, String itemID
			, String enterpriseNo
			, String enterpriseName
			, String userId
			) {
		
		StorageItem si = new StorageItem();
		
		si.setfID(Utils.getUUID());
		si.setStorageID(storageID);
		si.setItemID(itemID);
		
		si.setStorehouseID(storehouseID);
		
		si.setUserId(userId);
		si.setEnterpriseNo(enterpriseNo);
		si.setEnterpriseName(enterpriseName);

		si.setMinQuantity(new BigDecimal("0"));
		si.setMaxQuantity(new BigDecimal("0"));
		
		si.setItemQuantityL(new BigDecimal("0"));
		si.setItemQuantityFrozen(new BigDecimal("0"));

		si.setPieceQuantityL(new BigDecimal("0"));
		si.setPieceQuantityFrozen(new BigDecimal("0"));
		
		si.setCreateDatetime(Utils.getCurrentDateTime());

		si.setUpperShelf(0);

		dao.insert(si);
		
		return si;
	}

	//更新预占库存数量
	@Transactional
	@Override
	public StorageItem updateQuantityFrozen(
			String storageID
			, String itemID
			, BigDecimal itemQuantityFrozen
			, BigDecimal pieceQuantityFrozen
			, String enterpriseNo
			, String enterpriseName
			, String userId
			) {
		
		StorageItem si = dao.getByNo(storageID, itemID);
		if(si==null) return null;
		
		si.setItemQuantityFrozen(si.getItemQuantityFrozen().add(itemQuantityFrozen));
		si.setPieceQuantityFrozen(si.getPieceQuantityFrozen().add(pieceQuantityFrozen));
		
		try {
			dao.update(si);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return si;
	}


	@Override
	public StorageItem packing(String userId ,String enterpriseNo ,String enterpriseName ){
		
		StorageItem obj = new StorageItem();
		String fID = Utils.getUUID();
		obj.setfID(fID);
		
		obj.setUpperShelf(0);
		
		obj.setMinQuantity(BigDecimal.ZERO);
		obj.setMaxQuantity(BigDecimal.ZERO);
		
		obj.setItemQuantityL(BigDecimal.ZERO);
		obj.setPieceQuantityL(BigDecimal.ZERO);
		
		obj.setItemQuantityFrozen(new BigDecimal("0"));
		obj.setPieceQuantityFrozen(new BigDecimal("0"));
		
		obj.setCreateDatetime(Utils.getCurrentDateTime());
		
		obj.setUserId(userId);
		obj.setEnterpriseNo(enterpriseNo);
		obj.setEnterpriseName(enterpriseName);
		
		obj.setVersion(0);
		
		return obj;
	}

	//零售专用
	//带图片的仓库物料档案列表（简单列表）
	@Override
	public JSONObject querySimple(JSONObject param, String ossServer) {
		
		JSONObject json = new JSONObject();
		//获取物料档案（不包含SKU条目）
		JSONObject data;
		try {
			data = dao.querySimple(param);
		} catch (SQLException e) {
			e.printStackTrace();
			
			json.put("code", -1);
			json.put("status", e.getMessage());
			json.put("msg", "failure");
			
			return json;
		}
		//开始装配
		
		JSONArray arrayItem = new JSONArray();
		
		JSONArray rows = data.getJSONArray("data");
		
		for(int i =0;i<rows.size();i++) {
			
			//转换成JSON
			JSONObject rowObject = rows.getJSONObject(i);
			//装配图片
			String imageurl = rowObject.getString("imageurl");
			JSONArray arrayImageurl = new JSONArray();
			if(imageurl!=null) {
				//单图
				//http://www.iune.cn/group1/M00/00/00/cxzWEVq2MjCAc8JsAAAuxlb_9jI617.jpg
				arrayImageurl = JSONArray.parseArray(imageurl);
				//[{"remoteFileName":"M00/00/01/cxzWEVuxsaGAGM53AABkeWyTCEw855.jpg","groupName":"group1","originalFilename":"131097612878657419_wmk.jpg"},{"remoteFileName":"M00/00/01/cxzWEVtZ24yAMd2MAACxW7HAcco856.jpg","groupName":"group1","originalFilename":"589d3de5N48cfbe46.jpg"},{"remoteFileName":"M00/00/01/cxzWEVtZVsKAEKl3AAAcaGOOVFo105.jpg","groupName":"group1","originalFilename":"ljdxm.jpg"},{"remoteFileName":"M00/00/00/cxzWEVtVQp-AMgkoAAAVTb55arQ384.png","groupName":"group1","originalFilename":"Untitled.png"}]
				//log.info(arrayImageurl.toJSONString());
				JSONObject jsonObject = arrayImageurl.getJSONObject(0);
				String groupName = jsonObject.getString("groupName");
				String remoteFileName = jsonObject.getString("remoteFileName");
				String url = ossServer + "/" + groupName + "/" + remoteFileName;
				//封面（单图）
				rowObject.put("pic", url);
			}
			/*
			JSONArray pics = new JSONArray();
			String images = rowObject.getString("images");
			JSONArray arrayImages = new JSONArray();
			if(images!=null) {
				//图集（多图片）
				//http://www.iune.cn/group1/M00/00/00/cxzWEVq2MjCAc8JsAAAuxlb_9jI617.jpg
				String ossServer = appConfigParams.getOssServer();//"http://www.iune.cn";
				arrayImages = JSONArray.parseArray(images);
				//[{"remoteFileName":"M00/00/01/cxzWEVuxsaGAGM53AABkeWyTCEw855.jpg","groupName":"group1","originalFilename":"131097612878657419_wmk.jpg"},{"remoteFileName":"M00/00/01/cxzWEVtZ24yAMd2MAACxW7HAcco856.jpg","groupName":"group1","originalFilename":"589d3de5N48cfbe46.jpg"},{"remoteFileName":"M00/00/01/cxzWEVtZVsKAEKl3AAAcaGOOVFo105.jpg","groupName":"group1","originalFilename":"ljdxm.jpg"},{"remoteFileName":"M00/00/00/cxzWEVtVQp-AMgkoAAAVTb55arQ384.png","groupName":"group1","originalFilename":"Untitled.png"}]
				log.info(arrayImages.toJSONString());
				for(Object obj : arrayImages) {
					JSONObject jsonObject = (JSONObject) obj;
					String groupName = jsonObject.getString("groupName");
					String remoteFileName = jsonObject.getString("remoteFileName");
					String url = ossServer + "/" + groupName + "/" + remoteFileName;

					JSONObject jsonPic = new JSONObject();
					jsonPic.put("goodsId", rowObject.getString("fID"));
					jsonPic.put("pic", url);
					pics.add(jsonPic);
				}
			}
			rowObject.put("pics", pics);
			*/
			BigDecimal minPrice = rowObject.getBigDecimal("salePrice");
			BigDecimal maxPrice = rowObject.getBigDecimal("salePrice");
		
			//设置最低售价和最高售价
			rowObject.put("minPrice", minPrice);
			rowObject.put("maxPrice", maxPrice);
			
			arrayItem.add(rowObject);
		}
		
		json.put("data", arrayItem);
		json.put("code", 0);
		json.put("msg", "success");
		json.put("total", data.getBigInteger("total"));

		return json;		
	}

	//库存金额（不再使用）
	@Override
	public BigDecimal getCostingAmount(String enterpriseNo) throws Throwable {
		List<Object> params = new ArrayList<Object>();
		params.add(enterpriseNo);

		return dao.getCostingAmount(params);
	}

	//库存数量（不再使用）
	@Override
	public BigDecimal getQuantityL(String enterpriseNo) throws Throwable {
		List<Object> params = new ArrayList<Object>();
		params.add(enterpriseNo);

		return dao.getQuantityL(params);
	}
	
	@Override
	public JSONObject newData(JSONObject data) {
		return dao.create(data);
	}
	
	@Override
	public JSONObject deleteData(JSONObject param) {
		//System.out.println("fileFactoryCreate.param-->>"+param.toJSONString());
		JSONArray ids = param.getJSONArray("ids");
		for(int i=0;i<ids.size();i++){
			String id = ids.getString(i);
			//这里可以增加是否可删除的判断
			
			dao.delete(id);
		}

		JSONObject data = new JSONObject();
		data.put("ids", ids);
		
		JSONObject json = new JSONObject();
		json.put("code", 0);
		json.put("msg", "success");
		json.put("data", data);
		
		return json;
	}

	/*
	在@Transaction注解中定义noRollbackFor和RollbackFor指定某种异常是否回滚。 
	@Transactional(noRollbackFor=RuntimeException.class) 
	@Transactional(RollbackFor=Exception.class) 
	*/
	@Transactional
	@Override
	public JSONObject saveData(JSONObject param) {
		//Spring的事务管理默认只对出现运行期异常(java.lang.RuntimeException及其子类)进行回滚。 
		//如果一个方法抛出Exception或者Checked异常，Spring事务管理默认不进行回滚。 
		// JSON转换Table
		//System.out.println(object);
		JSONObject data;
		try {
			data = this.save(param);
					
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", data);
			
			return json;
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			log.info("开始打印ParseException");
			e.printStackTrace();
			log.info("e.getMessage()-->>"+e.getMessage());
			log.info("完成打印ParseException");
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			
			return json;
		} 
	}
	
	/* (non-Javadoc)
	 * @see com.iune.erp.baseinfo.aaa#queryJDBC(com.alibaba.fastjson.JSONObject)
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
	@Override
	public JSONObject queryData(JSONObject param){
		//在此层面（ServiceImpl）统一处理异常，此层面直接被controller调用，面对BizData
		
		try {
			JSONObject jsonTable = dao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}
	
	@Override
	public JSONObject validData(JSONObject param) {
		// TODO Auto-generated method stub
		return null;
	}
	
	
	//入库登记
	@Transactional
	@Override
	public StorageItem storeRegister(
			String storageID
			, String storehouseID
//			, String storageNo
//			, String storageName
//			, String storageType
//			, String floorNo
			, String itemID
//			, String itemNo
//			, String itemDescribe
//			, String rationSize
//			, String unitCode
//			, String unitName
//			, String itemProperty
//			, String batchNo
			, BigDecimal itemQuantity
//			, BigDecimal accountAmount
//			, BigDecimal materialAmount
//			, BigDecimal workingAmount
//			, BigDecimal manufactAmount
//			, BigDecimal processAmount
			, BigDecimal costingAmount

			, BigDecimal pieceQuantity

			, String enterpriseNo
			, String enterpriseName
			, String userId
			) {
		
		StorageItem si = dao.getByNo(storageID, itemID);
		if(si==null) {
			si = this.insert(storageID, storehouseID, itemID, enterpriseNo, enterpriseName, userId);
		}
		
		//登记
		//数量
		si.setItemQuantityL(si.getItemQuantityL().add(itemQuantity));
		si.setPieceQuantityL(si.getPieceQuantityL().add(pieceQuantity));
		//金额
		si.setCostingAmount(si.getCostingAmount().add(costingAmount));
		//单位成本
//		BigDecimal costingAmountPer = si.getCostingAmount().divide(si.getItemQuantityL(), 6, RoundingMode.HALF_UP);
//		si.setCostingAmountPer(costingAmountPer);
		
		si.setDateIn(Utils.getCurrentDate());
		
//		try {
//			dao.update(si);
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return si;
		
		return dao.update(si);
	}

	//出库登记
	@Transactional
	@Override
	public StorageItem pickRegister(
			String storageID
			, String storehouseID
//			, String storageNo
//			, String storageName
//			, String storageType
//			, String floorNo
			, String itemID
//			, String itemNo
//			, String itemDescribe
//			, String rationSize
//			, String unitCode
//			, String unitName
//			, String itemProperty
//			, String batchNo
			, BigDecimal itemQuantity
//			, BigDecimal accountAmount
//			, BigDecimal materialAmount
//			, BigDecimal workingAmount
//			, BigDecimal manufactAmount
//			, BigDecimal processAmount
			, BigDecimal costingAmount

			, BigDecimal pieceQuantity
			, int frozenFlag

			, String enterpriseNo
			, String enterpriseName
			, String userId
			) {

		//登记
		StorageItem si = dao.getByNo(storageID, itemID);
		if(si==null) {
			si = this.insert(storageID, storehouseID, itemID, enterpriseNo, enterpriseName, userId);
		}
		
		si.setItemQuantityL(si.getItemQuantityL().subtract(itemQuantity));
		si.setPieceQuantityL(si.getPieceQuantityL().subtract(pieceQuantity));
		//金额
		si.setCostingAmount(si.getCostingAmount().subtract(costingAmount));
		//单位成本
//		BigDecimal costingAmountPer = si.getCostingAmount().divide(si.getItemQuantityL(), 6, RoundingMode.HALF_UP);
//		si.setCostingAmountPer(costingAmountPer);
		
		si.setDateOut(Utils.getCurrentDate());
		
		//减去客户订单预留数量
		if(frozenFlag==1) {
			si.setItemQuantityFrozen(si.getItemQuantityFrozen().subtract(itemQuantity));
			si.setPieceQuantityFrozen(si.getPieceQuantityFrozen().subtract(pieceQuantity));
		}

//		try {
//			dao.update(si);
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return si;
		
		return dao.update(si);
	}


	//出库登记
	@Transactional
	@Override
	public StorageItem pickRegister(
			StorageItem si
			, BigDecimal itemQuantity
//			, BigDecimal accountAmount
//			, BigDecimal materialAmount
//			, BigDecimal workingAmount
//			, BigDecimal manufactAmount
//			, BigDecimal processAmount
			, BigDecimal costingAmount

			, BigDecimal pieceQuantity
			, int frozenFlag

			, String enterpriseNo
			, String enterpriseName
			, String userId
			) {

		//登记
		
		si.setItemQuantityL(si.getItemQuantityL().subtract(itemQuantity));
		si.setPieceQuantityL(si.getPieceQuantityL().subtract(pieceQuantity));
		//金额
		si.setCostingAmount(si.getCostingAmount().subtract(costingAmount));
		//单位成本
//		BigDecimal costingAmountPer = si.getCostingAmount().divide(si.getItemQuantityL(), 6, RoundingMode.HALF_UP);
//		si.setCostingAmountPer(costingAmountPer);
		
		si.setDateOut(Utils.getCurrentDate());
		
		//减去客户订单预留数量
		if(frozenFlag==1) {
			si.setItemQuantityFrozen(si.getItemQuantityFrozen().subtract(itemQuantity));
			si.setPieceQuantityFrozen(si.getPieceQuantityFrozen().subtract(pieceQuantity));
		}

//		try {
//			dao.update(si);
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return si;
		
		return dao.update(si);
	}




}
